package org.dark.fund.service;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.dark.fund.api.IRateReturnService;
import org.dark.fund.dao.entity.RateReturn;
import org.dark.fund.dao.mapper.RateReturnMapper;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author wanlh
 * @since 2021-04-29
 */
@Service
public class RateReturnServiceImpl extends ServiceImpl<RateReturnMapper, RateReturn> implements IRateReturnService {

    @Override
    public Map<String, RateReturn> getTodayRate(List<String> fundCodes) {
        String date = DateUtil.today();
        // todo 日期是否要减一要确认一下
        date = DateUtil.format(DateUtil.yesterday(), "yyyy-MM-dd");
        date = bizDate();
        return lambdaQuery().in(RateReturn::getFundCode, fundCodes).eq(RateReturn::getFundDate, date)
                .list().stream().collect(Collectors.toMap(RateReturn::getFundCode, Function.identity()));
    }

    @Override
    public RateReturn getTodayRate(String fundCode) {
        String date = DateUtil.today();
        // todo 日期是否要减一要确认一下
        date = DateUtil.format(DateUtil.yesterday(), "yyyy-MM-dd");
        date = bizDate();
        return lambdaQuery().eq(RateReturn::getFundCode, fundCode).eq(RateReturn::getFundDate, date).one();
    }

    @Override
    public List<RateReturn> getRateRecently(String fundCode, int offset) {
        String date = DateUtil.today();
        date = bizDate();
        String dateOffset = DateUtil.format(DateUtil.offsetDay(DateUtil.date(), -offset), "yyyy-MM-dd");
        return lambdaQuery().eq(RateReturn::getFundCode, fundCode)
                .between(RateReturn::getFundDate, dateOffset, date).list();
    }

    @Override
    public RateReturn getMaxYearUp(String fundCode) {
        return lambdaQuery().eq(RateReturn::getFundCode, fundCode)
                .orderByDesc(RateReturn::getLastOneYearRate).last("limit 1").one();
    }

    @Override
    public RateReturn getMaxYearDown(String fundCode) {
        return lambdaQuery().eq(RateReturn::getFundCode, fundCode)
                .orderBy(true, false, RateReturn::getLastOneYearRate)
                .last("limit 1").one();
    }

    @Override
    public List<RateReturn> getYearEndUpRate(String fundCode) {
        return lambdaQuery().eq(RateReturn::getFundCode, fundCode).like(RateReturn::getFundDate, "-12-31").list();
    }

    @Override
    public double getYearUpRate(String fundCode) {
        List<RateReturn> rateReturns = lambdaQuery()
                .eq(RateReturn::getFundCode, fundCode).like(RateReturn::getFundDate, "-12-31").list();
        long upCount = rateReturns.stream().filter(fund -> fund.getLastOneYearRate().compareTo(BigDecimal.ZERO) >= 0).count();

        return 1.0 * upCount / rateReturns.size();
    }

    @Override
    public String bizDate() {
        return lambdaQuery().select(RateReturn::getFundDate).orderByDesc(RateReturn::getFundDate)
                .last("limit 1").one().getFundDate();
    }


}
